﻿using Quartz;
using RPAVIEW.views.EditPage;
using RPAVIEW.views.EditPage.flows;
using SUNRPA.CONTROLS.IMPL.domain;
using SUNRPA.CONTROLS.IMPL.domain.quartz;
using SUNRPA.CONTROLS.IMPL.util;
using System;
using System.Collections.Generic;
using System.Windows;

namespace RPAVIEW {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window {
        public EditHome eh;
        private Object MainWindowContent { get; set; }
        public MainWindow() {
            InitializeComponent();
            //读取当前用户的应用列表
            this.appPage.processList.ItemsSource = GetUserProcesses();
            List<Trigger<TimeTriggerEntry>> triggers = GetUserTriggers();
            this.triggerPage.triggerList.ItemsSource = triggers;
            //初始化流程调度任务
            this.InitScheduleJob(triggers);
            this.MainWindowContent = this.Content;
        }

        public List<ProcessInfo> GetUserProcesses() { 
            HttpUtil httpUtil = HttpUtil.getInstance(SystemUtil.GetAPPConfig("ControlBaseIp") + SystemUtil.GetAPPConfig("ProcessUri"));
            UserInfo userinfo = (Application.Current as App).currentUser;
            HttpResponse<List<ProcessInfo>> res = httpUtil.SendGet<List<ProcessInfo>>("/list",new Dictionary<string, string> { {"userId", userinfo.accountId} });
            return res.Data;
        }

        public List<Trigger<TimeTriggerEntry>> GetUserTriggers() { 
            HttpUtil httpUtil = HttpUtil.getInstance(SystemUtil.GetAPPConfig("ControlBaseIp") + SystemUtil.GetAPPConfig("TriggerUri"));
            UserInfo userinfo = (Application.Current as App).currentUser;
            HttpResponse<List<Trigger<TimeTriggerEntry>>> res = httpUtil.SendGet<List<Trigger<TimeTriggerEntry>>>("/list",new Dictionary<string, string> { {"accountId", userinfo.accountId} });
            return res.Data;
        }

        #region 打开流程旧
        /*private void openApp(object sender, RoutedEventArgs e) {
            FolderBrowserDialog fd = FileUtil.OpenFloderSelectDialog();
            if (fd.ShowDialog() == System.Windows.Forms.DialogResult.OK  ){
                eh = new EditHome();
                eh.GoBackEvent += new EditHome.GoBackDelgage(recover);
                if (string.IsNullOrEmpty(fd.SelectedPath)){
                    throw new RpaRuntimeException("文件夹路径不能为空");
                }
                string golbleDataJson = File.ReadAllText(fd.SelectedPath + DefaultContents.SERIALIZE_GOLBLE);
                string flowItemsJson = File.ReadAllText(fd.SelectedPath + DefaultContents.SERIALIZE_FLOWITEMS);
                JsonSerializerSettings set  = new JsonSerializerSettings();
                set.TypeNameHandling = TypeNameHandling.Auto;
                ConcurrentDictionary<string, ConcurrentDictionary<string, RPAVariableDefineWrapper>>? golbleData = JsonConvert.DeserializeObject<ConcurrentDictionary<string, ConcurrentDictionary<string, RPAVariableDefineWrapper>>>(golbleDataJson, set);
                JsonSerializer serializer = new JsonSerializer();
                List<FlowItem>? flowItems = JsonConvert.DeserializeObject<List<FlowItem>>(flowItemsJson, set);
                //List<FlowItem>? flowItems = DataUtil.TempDeserialize(flowItemsJson);
                eh.DataContext = golbleData;
                Dictionary<int, int> rangeTags = new Dictionary<int, int>();
                for(int i = 0; i < flowItems.Count; i++) { 
                    FlowItem item = flowItems[i];
                    i = GenertSubItem(0, item, flowItems);
                }
                this.Content = eh;
            }
        }*/
        #endregion

        public int GenertSubItem(int currentStep, FlowItem item, List<FlowItem> items) {
            if(!string.IsNullOrEmpty(item.ParentKey)) { 
                currentStep--;
            }
            int endIndex = item.Index;
            FlowItemView fv = new FlowItemView(item);
            fv.DataContext = item;
            fv.itemTitle.Text = item.ControlName;
            fv.Margin = new Thickness(currentStep * 20, 0, 0, 0);
            eh.FlowItems.Children.Add(fv);
            if(item.EndTag != null) {
                endIndex = item.EndTag.Index;
                for(int i = item.Index + 1; i < item.EndTag.Index; i++) { 
                    GenertSubItem(currentStep + 1, items[i], items);
                }
                FlowItemView end = new FlowItemView(item.EndTag);
                end.DataContext = item.EndTag;
                end.itemTitle.Text = item.EndTag.ItemInfo;
                end.Margin = new Thickness(currentStep * 20, 0, 0, 0);
                fv.EndTagView = end;
                eh.FlowItems.Children.Add(end);
            }
            return endIndex;
        }

        public void recover() {
            this.appPage.processList.ItemsSource = GetUserProcesses();
            this.Content = MainWindowContent;
        }

        private void ShutDownApp(object sender, EventArgs e) {
            Application.Current.Shutdown();
        }
        /// <summary>
        /// 初始化触发器任务（目前只有时间触发器，暂时写死）
        /// </summary>
        private void InitScheduleJob(List<Trigger<TimeTriggerEntry>> triggers) {
            App app = Application.Current as App;
            ScheduleUtil scheduleUtil = app.schedule;
            foreach (Trigger<TimeTriggerEntry> trigger in triggers) {
                if(trigger.enable ?? false) {
                    if(trigger.processInfo == null || trigger.triggerEntry == null || string.IsNullOrEmpty(trigger.processInfo.processName)) { 
                        continue;
                    }
                    TimeTriggerEntry entry = trigger.triggerEntry;
                    if(entry.isTimeEnded ?? false && entry.endDateTime <= DateTime.Now) { 
                        continue;
                    }
                    IJobDetail job = JobBuilder.Create<FlowExeJob>().WithIdentity(trigger.processInfo.processName + "-" + trigger.triggerName)
                        .SetJobData(new JobDataMap { 
                            new KeyValuePair<string, object>("processInfo", trigger.processInfo),
                            new KeyValuePair<string, object>("mainWindow", this),
                        }).Build();
                    TriggerBuilder tbuilder = TriggerBuilder.Create()
                        .WithIdentity(trigger.triggerName)
                        .WithSchedule(CronScheduleBuilder.CronSchedule(entry.GenerateExpression()).WithMisfireHandlingInstructionDoNothing())
                        .StartNow();
                    if(entry.isTimeEnded ?? false) { 
                        tbuilder.EndAt(entry.endDateTime);
                    }
                    scheduleUtil.SetJob(job, tbuilder.Build());
                }
            }
        }
    }
}
